#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pandas as pd
import sys
import warnings
warnings.filterwarnings('ignore')

def generate_sheet_names(num_sheets):
    """
    根据sheet数量生成对应的sheet名称
    
    参数:
    num_sheets: sheet数量
    
    返回:
    sheet名称列表
    """
    # 中文数字映射
    chinese_numbers = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
    
    sheet_names = []
    for i in range(num_sheets):
        if i < len(chinese_numbers):
            sheet_names.append(f'第{chinese_numbers[i]}次全量')
        else:
            # 如果超过10个，使用数字表示
            sheet_names.append(f'第{i+1}次全量')
    
    return sheet_names

def classify_test_cases(excel_path, num_sheets):
    """
    分类处理Excel中的测试用例
    
    参数:
    excel_path: Excel文件路径
    num_sheets: sheet数量
    """
    
    try:
        # 根据sheet数量生成sheet名称列表
        required_sheets = generate_sheet_names(num_sheets)
        print(f"需要处理的sheet数量: {num_sheets}")
        print(f"期望的sheet名称: {required_sheets}")
        
        # 读取Excel文件的所有sheet
        xls = pd.ExcelFile(excel_path)
        print(f"文件中现有的sheet: {xls.sheet_names}")
        
        # 检查必要的sheet是否存在
        existing_sheets = [sheet for sheet in required_sheets if sheet in xls.sheet_names]
        missing_sheets = [sheet for sheet in required_sheets if sheet not in xls.sheet_names]
        
        if not existing_sheets:
            print(f"错误: 没有找到任何需要的sheet")
            return
        
        if missing_sheets:
            print(f"警告: 缺少以下sheet: {missing_sheets}")
            print(f"将继续处理找到的sheet: {existing_sheets}")
        
        # 读取所有sheet的数据
        sheet_data = {}
        for sheet_name in existing_sheets:
            df = pd.read_excel(xls, sheet_name=sheet_name)
            sheet_data[sheet_name] = df
        
        # 打印每个sheet的原始行数
        print("\n各sheet原始数据情况:")
        total_rows = 0
        for sheet_name, df in sheet_data.items():
            row_count = len(df)
            total_rows += row_count
            print(f"  {sheet_name}: {row_count} 行")
        print(f"  总计: {total_rows} 行原始数据")
        
        # 检查必要的列是否存在
        required_columns = ['Module', 'name', 'result']
        for sheet_name, df in sheet_data.items():
            missing_cols = [col for col in required_columns if col not in df.columns]
            if missing_cols:
                print(f"警告: sheet '{sheet_name}' 中缺少必要的列: {missing_cols}")
                # 尝试查找相似的列名
                similar_cols = {}
                for col in missing_cols:
                    similar = [c for c in df.columns if col.lower() in c.lower() or c.lower() in col.lower()]
                    if similar:
                        similar_cols[col] = similar
                
                if similar_cols:
                    print(f"  可能的相似列名: {similar_cols}")
                return
        
        # 标准化列名（去除可能的空格）
        for df in sheet_data.values():
            df.columns = df.columns.str.strip()
        
        # 处理数据，确保关键字段为字符串类型
        print("\n数据处理详情:")
        for sheet_name, df in sheet_data.items():
            original_count = len(df)
            
            # 检查关键字段的NaN值
            module_na_count = df['Module'].isna().sum()
            name_na_count = df['name'].isna().sum()
            
            if module_na_count > 0 or name_na_count > 0:
                print(f"  {sheet_name}: 发现 {module_na_count} 个Module为NaN, {name_na_count} 个name为NaN的值")
            
            # 确保Module和name列为字符串类型
            df['Module'] = df['Module'].astype(str).str.strip()
            df['name'] = df['name'].astype(str).str.strip()
            
            # 创建一个唯一的标识列，组合Module和name
            df['module_name_key'] = df['Module'] + '|' + df['name']
            
            # 检查重复的(Module, name)组合
            duplicate_count = df.duplicated(subset=['module_name_key']).sum()
            if duplicate_count > 0:
                print(f"  警告: {sheet_name} 中发现 {duplicate_count} 个重复的(Module, name)组合")
            
            print(f"  {sheet_name}: 处理完成，保持 {original_count} 行数据")
        
        # 开始构建用例信息，以(Module, name)作为唯一标识
        print("\n开始构建用例信息...")
        
        # 创建一个字典来存储每个用例的信息
        # 结构: {module_name_key: {module: 模块名, name: 用例名, results: {sheet_name: 结果}}}
        case_info_dict = {}
        
        # 遍历每个sheet，收集用例信息
        for sheet_name, df in sheet_data.items():
            print(f"  处理 {sheet_name}...")
            for idx, row in df.iterrows():
                module = row['Module']
                name = row['name']
                module_name_key = row['module_name_key']
                result = row['result']
                
                # 初始化用例信息
                if module_name_key not in case_info_dict:
                    case_info_dict[module_name_key] = {
                        'module': module,
                        'name': name,
                        'results': {}
                    }
                
                # 记录该sheet的结果
                case_info_dict[module_name_key]['results'][sheet_name] = result
        
        print(f"总共发现 {len(case_info_dict)} 个唯一的(Module, name)组合")
        
        # 创建结果DataFrame
        must_pass_data = []
        possible_failed_data = []
        must_failed_data = []
        
        print(f"\n开始对 {len(case_info_dict)} 个用例进行分类...")
        
        for idx, (module_name_key, info) in enumerate(case_info_dict.items()):
            if idx % 5000 == 0:
                print(f"  已处理 {idx}/{len(case_info_dict)} 个用例...")
            
            # 准备用例信息行
            case_row = {
                'Module': info['module'],
                'name': info['name'],
            }
            
            # 添加每个sheet的结果到case_row
            for sheet_name in existing_sheets:
                case_row[sheet_name] = info['results'].get(sheet_name, '未执行')
            
            # 统计fail次数（只统计有结果的情况，排除'未执行'）
            results_list = []
            for sheet_name in existing_sheets:
                result = info['results'].get(sheet_name)
                if result is not None and result != '未执行':
                    # 转换为字符串并小写，去除空格
                    result_str = str(result).lower().strip()
                    results_list.append(result_str)
            
            # 统计fail次数 - 注意：这里是"fail"，不是"failed"
            fail_count = sum(1 for r in results_list if r == 'fail')
            total_results = len(results_list)  # 实际有结果的次数
            
            # 分类
            if fail_count == 0:
                # 没有fail结果
                must_pass_data.append(case_row)
            elif fail_count == total_results:
                # 所有结果都是fail
                must_failed_data.append(case_row)
            else:
                # 部分fail
                possible_failed_data.append(case_row)
        
        print(f"  用例分类完成!")
        
        # 转换为DataFrame
        must_pass_df = pd.DataFrame(must_pass_data)
        possible_failed_df = pd.DataFrame(possible_failed_data)
        must_failed_df = pd.DataFrame(must_failed_data)
        
        # 保存结果到新的Excel文件
        if excel_path.endswith('.xlsx'):
            output_path = excel_path.replace('.xlsx', '_summary.xlsx')
        elif excel_path.endswith('.xls'):
            output_path = excel_path.replace('.xls', '_summary.xlsx')
        else:
            output_path = excel_path + '_summary.xlsx'
        
        # 使用openpyxl创建writer
        with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
            # 写入原始数据
            for sheet_name in existing_sheets:
                sheet_data[sheet_name].to_excel(writer, sheet_name=sheet_name, index=False)
            
            # 写入分类结果
            if not must_pass_df.empty:
                must_pass_df.to_excel(writer, sheet_name='mustPass', index=False)
            
            if not possible_failed_df.empty:
                possible_failed_df.to_excel(writer, sheet_name='possibleFailed', index=False)
            
            if not must_failed_df.empty:
                must_failed_df.to_excel(writer, sheet_name='mustFailed', index=False)
        
        print("=" * 60)
        print("处理完成！")
        print(f"结果已保存到: {output_path}")
        print("\n分类统计:")
        print(f"  mustPass (始终通过): {len(must_pass_data)} 个用例")
        print(f"  possibleFailed (可能失败): {len(possible_failed_data)} 个用例")
        print(f"  mustFailed (始终失败): {len(must_failed_data)} 个用例")
        
        total_cases = len(must_pass_data) + len(possible_failed_data) + len(must_failed_data)
        print(f"  汇总后总用例数: {total_cases}")
        
        # 显示一些统计信息
        if total_cases > 0:
            print(f"\n总计: {total_cases} 个用例")
            print(f"  通过率: {len(must_pass_data)/total_cases*100:.1f}%")
            print(f"  可能失败率: {len(possible_failed_data)/total_cases*100:.1f}%")
            print(f"  失败率: {len(must_failed_data)/total_cases*100:.1f}%")
        
        # 打印详细的数据统计
        print(f"\n详细统计:")
        print(f"  各sheet原始用例数量:")
        for sheet_name in existing_sheets:
            original_count = sheet_data[sheet_name].shape[0]
            print(f"    {sheet_name}: {original_count} 行")
        
        print(f"\n  汇总统计:")
        print(f"    发现的总(Module, name)组合数: {len(case_info_dict)}")
        print(f"    分类后用例总数: {total_cases}")
        
        # 检查是否有用例在所有sheet中都不存在（理论上不应该有）
        missing_cases = []
        for module_name_key, info in case_info_dict.items():
            if not info['results']:  # 如果没有结果
                missing_cases.append(module_name_key)
        
        if missing_cases:
            print(f"\n警告: 发现 {len(missing_cases)} 个用例在所有sheet中都没有结果!")
        
        print("=" * 60)
        
    except Exception as e:
        print(f"处理过程中发生错误: {str(e)}")
        import traceback
        traceback.print_exc()

def main():
    """
    主函数
    """
    if len(sys.argv) < 3:
        print("使用方法: python summary_total.py <sheet数量> <excel文件路径>")
        print("示例: python summary_total.py 6 a.xlsx")
        print("       python summary_total.py 3 test_cases.xlsx")
        print("\n注意:")
        print("  1. sheet数量表示需要处理的全量测试次数")
        print("  2. 表格中的结果列应该是'fail'而不是'failed'")
        print("  3. 支持的sheet命名格式: '第一次全量', '第二次全量', '第三次全量'...")
        return
    
    try:
        num_sheets = int(sys.argv[1])
        if num_sheets <= 0:
            print("错误: sheet数量必须是正整数")
            return
    except ValueError:
        print("错误: sheet数量必须是整数")
        return
    
    excel_file = sys.argv[2]
    
    try:
        classify_test_cases(excel_file, num_sheets)
    except FileNotFoundError:
        print(f"错误: 文件 '{excel_file}' 不存在")
    except Exception as e:
        print(f"错误: {str(e)}")

if __name__ == "__main__":
    main()
